home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 1 / Gold Medal Software Volume 1 (Gold Medal) (1994).iso / graphics / tierra40.arj / TIERRA / PARSE1.C < prev    next >
Text File  |  1992-09-09  |  28KB  |  797 lines

  1. /* parse1.c   9-9-92  parser functions for instruction set 1 */
  2. /* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */
  3.  
  4. #if INST == 1
  5.  
  6. /* in INST == 1, the array of registers maps into the registers ax, bx, cx, dx
  7.    as follows:  c.re[0] = ax, c.re[1] = bx, c.re[2] = cx, c.re[3] = dx
  8.  
  9.     {0x00, "nop0", nop, pnop},
  10.     {0x01, "nop1", nop, pnop},
  11.     {0x02, "not0", not0, pnot0},
  12.     {0x03, "shl", shl, pshl},
  13.     {0x04, "zero", movdd, pzero},
  14.     {0x05, "ifz", ifz, pifz},
  15.     {0x06, "sub_ab", math, psub_ab},
  16.     {0x07, "sub_ac", math, psub_ac},
  17.     {0x08, "inc_a", math, pinc_a},
  18.     {0x09, "inc_b", math, pinc_b},
  19.     {0x0a, "dec_c", math, pdec_c},
  20.     {0x0b, "inc_c", math, pinc_c},
  21.     {0x0c, "pushax", push, ppushax},
  22.     {0x0d, "pushbx", push, ppushbx},
  23.     {0x0e, "pushcx", push, ppushcx},
  24.     {0x0f, "pushdx", push, ppushdx},
  25.     {0x10, "popax", pop, ppopax},
  26.     {0x11, "popbx", pop, ppopbx},
  27.     {0x12, "popcx", pop, ppopcx},
  28.     {0x13, "popdx", pop, ppopdx},
  29.     {0x14, "jmp", adr, ptjmp},
  30.     {0x15, "jmpb", adr, ptjmpb},
  31.     {0x16, "call", tcall, ptcall},
  32.     {0x17, "ret", pop, pret},
  33.     {0x18, "movcd", movdd, pmovdc},
  34.     {0x19, "movab", movdd, pmovba},
  35.     {0x1a, "movii", movii, pmovii},
  36.     {0x1b, "adr", adr, padr},
  37.     {0x1c, "adrb", adr, padrb},
  38.     {0x1d, "adrf", adr, padrf},
  39.     {0x1e, "mal", malchm, pmal},
  40.     {0x1f, "divide", divide, pdivide}
  41. */
  42.  
  43. void pnop(ce) /* do nothing */
  44. Pcells  ce;
  45. {   is.iip = is.dib = 1;
  46. }
  47.  
  48.  
  49. /* void not0(ce) *(is.dreg) ^= (1 + flaw(ce));
  50.  * is.dreg = destination register, whose bit will be flipped
  51.  * is.dmod = value by which to modulus destination register
  52.  * is.dran = range within which to contain destination register
  53.  */
  54. void pnot0(ce) /* flip low order bit of cx */
  55. Pcells  ce;
  56. {   is.iip = is.dib = 1;
  57.     if (is.eins->exec)
  58.         return ;
  59.     is.dreg = &(ce->c.re[2]);
  60.     is.dran = SoupSize;
  61. }
  62.  
  63.  
  64. /* void shl(ce) *(is.dreg) <<= (Reg) (1 + flaw(ce));
  65.  * is.dreg = destination register, whose bits will be shifted left
  66.  * is.dmod = value by which to modulus destination register
  67.  * is.dran = range within which to contain destination register
  68.  */
  69. void pshl(ce) /* shift left all register of cx */
  70. Pcells  ce;
  71. {   is.iip = is.dib = 1;
  72.     if (is.eins->exec)
  73.         return ;
  74.     is.dreg = &(ce->c.re[2]);
  75.     is.dran = SoupSize;
  76. }
  77.  
  78. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  79.  * is.dreg = destination register, where moved value will be placed
  80.  * is.sval = value to be placed in the dest reg
  81.  * is.dmod = value by which to modulus destination register
  82.  * is.dran = range within which to contain destination register
  83.  */
  84. void pzero(ce) /* cx = 0 */
  85. Pcells  ce;
  86. {   is.iip = is.dib = 1;
  87.     if (is.eins->exec)
  88.         return ;
  89.     is.dreg = &(ce->c.re[2]);
  90.     is.sval = 0;
  91. }
  92.  
  93. /* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2;
  94.  * is.sval  = value to test for zero
  95.  * is.sval2 = amount to increment IP if is.sval == 0
  96.  * is.iip   = amount to increment IP if is.sval != 0
  97.  */
  98. void pifz(ce) /* execute next instruction, if is.sval == 0 */
  99. Pcells  ce;
  100. {   is.iip = is.dib = 1;
  101.     if (is.eins->exec)
  102.         return ;
  103.     is.sval = ce->c.re[2];
  104.     is.sval2 = 2;
  105. }
  106.  
  107. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  108.  * is.dreg  = destination register, where calculation will be stored
  109.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  110.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  111.  * is.dmod  = value by which to modulus destination register
  112.  * is.dran  = range within which to contain destination register
  113.  */
  114. void psub_ab(ce) /* cx = ax - bx */
  115. Pcells  ce;
  116. {   is.iip = is.dib = 1;
  117.     if (is.eins->exec)
  118.         return ;
  119.     is.dreg = &(ce->c.re[2]);
  120.     is.sval = ce->c.re[0];
  121.     is.sval2 = -ce->c.re[1];
  122.     is.dran = SoupSize;
  123. }
  124.  
  125. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  126.  * is.dreg  = destination register, where calculation will be stored
  127.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  128.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  129.  * is.dmod  = value by which to modulus destination register
  130.  * is.dran  = range within which to contain destination register
  131.  */
  132. void psub_ac(ce) /* ax = ax - cx */
  133. Pcells  ce;
  134. {   is.iip = is.dib = 1;
  135.     if (is.eins->exec)
  136.         return ;
  137.     is.dreg = &(ce->c.re[0]);
  138.     is.sval = ce->c.re[0];
  139.     is.sval2 = -ce->c.re[2];
  140.     is.dmod = SoupSize;
  141. }
  142.  
  143. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  144.  * is.dreg  = destination register, where calculation will be stored
  145.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  146.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  147.  * is.dmod  = value by which to modulus destination register
  148.  * is.dran  = range within which to contain destination register
  149.  */
  150. void pinc_a(ce) /* ax++ */
  151. Pcells  ce;
  152. {   is.iip = is.dib = 1;
  153.     if (is.eins->exec)
  154.         return ;
  155.     is.dreg = &(ce->c.re[0]);
  156.     is.sval = ce->c.re[0];
  157.     is.sval2 = 1;
  158.     is.dmod = SoupSize;
  159. }
  160.  
  161. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  162.  * is.dreg  = destination register, where calculation will be stored
  163.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  164.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  165.  * is.dmod  = value by which to modulus destination register
  166.  * is.dran  = range within which to contain destination register
  167.  */
  168. void pinc_b(ce) /* bx++ */
  169. Pcells  ce;
  170. {   is.iip = is.dib = 1;
  171.     if (is.eins->exec)
  172.         return ;
  173.     is.dreg = &(ce->c.re[1]);
  174.     is.sval = ce->c.re[1];
  175.     is.sval2 = 1;
  176.     is.dmod = SoupSize;
  177. }
  178.  
  179. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  180.  * is.dreg  = destination register, where calculation will be stored
  181.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  182.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  183.  * is.dmod  = value by which to modulus destination register
  184.  * is.dran  = range within which to contain destination register
  185.  */
  186. void pdec_c(ce) /* cx-- */
  187. Pcells  ce;
  188. {   is.iip = is.dib = 1;
  189.     if (is.eins->exec)
  190.         return ;
  191.     is.dreg = &(ce->c.re[2]);
  192.     is.sval = ce->c.re[2];
  193.     is.sval2 = -1;
  194.     is.dran = SoupSize;
  195. }
  196.  
  197. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  198.  * is.dreg  = destination register, where calculation will be stored
  199.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  200.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  201.  * is.dmod  = value by which to modulus destination register
  202.  * is.dran  = range within which to contain destination register
  203.  */
  204. void pinc_c(ce) /* cx++ */
  205. Pcells  ce;
  206. {   is.iip = is.dib = 1;
  207.     if (is.eins->exec)
  208.         return ;
  209.     is.dreg = &(ce->c.re[2]);
  210.     is.sval = ce->c.re[2];
  211.     is.sval2 = 1;
  212.     is.dran = SoupSize;
  213. }
  214.  
  215. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  216.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  217.  * is.sval = value to be pushed onto the stack
  218.  */
  219. void ppushax(ce) /* push ax onto stack */
  220. Pcells  ce;
  221. {   is.iip = is.dib = 1;
  222.     if (is.eins->exec)
  223.         return ;
  224.     is.sval = ce->c.re[0];
  225. }
  226.  
  227. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  228.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  229.  * is.sval = value to be pushed onto the stack
  230.  */
  231. void ppushbx(ce) /* push bx onto stack */
  232. Pcells  ce;
  233. {   is.iip = is.dib = 1;
  234.     if (is.eins->exec)
  235.         return ;
  236.     is.sval = ce->c.re[1];
  237. }
  238.  
  239. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  240.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  241.  * is.sval = value to be pushed onto the stack
  242.  */
  243. void ppushcx(ce) /* push cx onto stack */
  244. Pcells  ce;
  245. {   is.iip = is.dib = 1;
  246.     if (is.eins->exec)
  247.         return ;
  248.     is.sval = ce->c.re[2];
  249. }
  250.  
  251. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  252.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  253.  * is.sval = value to be pushed onto the stack
  254.  */
  255. void ppushdx(ce) /* push dx onto stack */
  256. Pcells  ce;
  257. {   is.iip = is.dib = 1;
  258.     if (is.eins->exec)
  259.         return ;
  260.     is.sval = ce->c.re[3];
  261. }
  262.  
  263. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  264.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  265.  * is.dreg = destination register, where value popped off stack will go
  266.  * is.dmod = value by which to modulus destination register
  267.  * is.dran = range within which to contain destination register
  268.  */
  269. void ppopax(ce) /* pop ax off of stack */
  270. Pcells  ce;
  271. {   is.iip = is.dib = 1;
  272.     if (is.eins->exec)
  273.         return ;
  274.     is.dreg = &(ce->c.re[0]);
  275.     is.dmod = SoupSize;
  276. }
  277.  
  278. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  279.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  280.  * is.dreg = destination register, where value popped off stack will go
  281.  * is.dmod = value by which to modulus destination register
  282.  * is.dran = range within which to contain destination register
  283.  */
  284. void ppopbx(ce) /* pop bx off of stack */
  285. Pcells  ce;
  286. {   is.iip = is.dib = 1;
  287.     if (is.eins->exec)
  288.         return ;
  289.     is.dreg = &(ce->c.re[1]);
  290.     is.dmod = SoupSize;
  291. }
  292.  
  293. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  294.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  295.  * is.dreg = destination register, where value popped off stack will go
  296.  * is.dmod = value by which to modulus destination register
  297.  * is.dran = range within which to contain destination register
  298.  */
  299. void ppopcx(ce) /* pop cx off of stack */
  300. Pcells  ce;
  301. {   is.iip = is.dib = 1;
  302.     if (is.eins->exec)
  303.         return ;
  304.     is.dreg = &(ce->c.re[2]);
  305.     is.dran = SoupSize;
  306. }
  307.  
  308. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  309.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  310.  * is.dreg = destination register, where value popped off stack will go
  311.  * is.dmod = value by which to modulus destination register
  312.  * is.dran = range within which to contain destination register
  313.  */
  314. void ppopdx(ce) /* pop dx off of stack */
  315. Pcells  ce;
  316. {   is.iip = is.dib = 1;
  317.     if (is.eins->exec)
  318.         return ;
  319.     is.dreg = &(ce->c.re[3]);
  320.     is.dran = SoupSize;
  321. }
  322.  
  323. /* void adr(ce) find address of a template
  324.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  325.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  326.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  327.  * is.dval  = starting address for forward search
  328.  * is.dval2 = starting address for backward search
  329.  * is.dreg  = destination register where target address will be stored
  330.  * is.dreg2 = destination register where template size will be stored
  331.  * is.dreg3 = destination register where offset of target will be stored
  332.  * is.sval  = return address if template size = 0
  333.  * is.sval2 = template size, 0 = no template
  334.  * is.sval3 = search limit, and return for distance actually searched
  335.  * is.dmod  = modulus value for is.dreg
  336.  * is.dmod2 = modulus value for is.dreg2
  337.  * is.dmod3 = modulus value for is.dreg3
  338.  * is.dran  = range to maintain for is.dreg
  339.  * is.dran2 = range to maintain for is.dreg2
  340.  * is.dran3 = range to maintain for is.dreg3
  341.  */
  342. void ptjmp(ce) /* outward template jump */
  343. Pcells  ce;
  344. {   I32s    a, s = 0;
  345.  
  346.     is.iip = is.dib = 1;
  347.     if (is.eins->exec)
  348.         return ;
  349.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  350.     while(1) /* find size of template, s = size */
  351.     {   
  352. #if PLOIDY == 1
  353.     if(soup[ad(a + s)].inst != Nop0 &&
  354.            soup[ad(a + s)].inst != Nop1)
  355. #else /* PLOIDY > 1 */
  356.     if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  357.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  358. #endif /* PLOIDY > 1 */
  359.             break;
  360.         s++;
  361.     }
  362.     is.dreg  = &(ce->c.ip); /* destination register for address */
  363.     is.dreg2 = &(ce->c.re[3]); /* destination register for template size */
  364.     is.dreg3 = &BitBucket;
  365.     is.sval  = a;  /* if template size == 0, increment IP */
  366.     is.sval2 = s;  /* size of template */
  367.     is.sval3 = Search_limit;
  368.     is.dval  = ad(a + s + 1); /* start address for forward search */
  369.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  370.     is.dmod  = SoupSize;
  371.     is.dran2 = SoupSize;
  372.     is.mode  = 0; /* outward jump */
  373.     is.mode2 = 1;
  374.     is.dib = 1;
  375.     is.iip = 0;
  376. }
  377.  
  378. /* void adr(ce) find address of a template
  379.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  380.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  381.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  382.  * is.dval  = starting address for forward search
  383.  * is.dval2 = starting address for backward search
  384.  * is.dreg  = destination register where target address will be stored
  385.  * is.dreg2 = destination register where template size will be stored
  386.  * is.dreg3 = destination register where offset of target will be stored
  387.  * is.sval  = return address if template size = 0
  388.  * is.sval2 = template size, 0 = no template
  389.  * is.sval3 = search limit, and return for distance actually searched
  390.  * is.dmod  = modulus value for is.dreg
  391.  * is.dmod2 = modulus value for is.dreg2
  392.  * is.dmod3 = modulus value for is.dreg3
  393.  * is.dran  = range to maintain for is.dreg
  394.  * is.dran2 = range to maintain for is.dreg2
  395.  * is.dran3 = range to maintain for is.dreg3
  396.  */
  397. void ptjmpb(ce) /* backward template jump */
  398. Pcells  ce;
  399. {   I32s    a, s = 0;
  400.  
  401.     is.iip = is.dib = 1;
  402.     if (is.eins->exec)
  403.         return ;
  404.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  405.     while(1) /* find size of template, s = size */
  406.     {   
  407. #if PLOIDY == 1
  408.     if(soup[ad(a + s)].inst != Nop0 &&
  409.            soup[ad(a + s)].inst != Nop1)
  410. #else /* PLOIDY > 1 */
  411.     if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  412.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  413. #endif /* PLOIDY > 1 */
  414.             break;
  415.         s++;
  416.     }
  417.     is.dreg  = &(ce->c.ip); /* destination register for address */
  418.     is.dreg2 = &(ce->c.re[3]); /* destination register for template size */
  419.     is.dreg3 = &BitBucket;
  420.     is.sval  = a;  /* if template size == 0, increment IP */
  421.     is.sval2 = s;  /* size of template */
  422.     is.sval3 = Search_limit;
  423.     is.dmod  = SoupSize;
  424.     is.dran2 = SoupSize;
  425.     is.dval  = ad(a + s + 1); /* start address for forward search */
  426.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  427.     is.mode  = 2; /* backward jump */
  428.     is.mode2 = 2;
  429.     is.dib = 1;
  430.     is.iip = 0;
  431. }
  432.  
  433. /* void tcall(ce) adr(ce); push(ce); */
  434. /* void adr(ce) find address of a template
  435.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  436.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  437.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  438.  * is.dval  = starting address for forward search
  439.  * is.dval2 = starting address for backward search
  440.  * is.dreg  = destination register where target address will be stored
  441.  * is.dreg2 = destination register where template size will be stored
  442.  * is.dreg3 = destination register where offset of target will be stored
  443.  * is.sval  = return address if template size = 0
  444.  * is.sval2 = template size, 0 = no template
  445.  * is.sval3 = search limit, and return for distance actually searched
  446.  * is.dmod  = modulus value for is.dreg
  447.  * is.dmod2 = modulus value for is.dreg2
  448.  * is.dmod3 = modulus value for is.dreg3
  449.  * is.dran  = range to maintain for is.dreg
  450.  * is.dran2 = range to maintain for is.dreg2
  451.  * is.dran3 = range to maintain for is.dreg3
  452.  */
  453. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  454.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  455.  * is.sval = value to be pushed onto the stack
  456.  */
  457. void ptcall(ce) /* push ip to stack, outward template jump */
  458. Pcells  ce;     /* this maps to adr followed by push */
  459. {   I32s    a, s = 0;
  460.  
  461.     is.iip = is.dib = 1;
  462.     if (is.eins->exec)
  463.         return ;
  464.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  465.     while(1) /* find size of template, s = size */
  466.     {
  467. #if PLOIDY == 1
  468.     if(soup[ad(a + s)].inst != Nop0 &&
  469.            soup[ad(a + s)].inst != Nop1)
  470. #else /* PLOIDY > 1 */
  471.     if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  472.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  473. #endif /* PLOIDY > 1 */
  474.             break;
  475.         s++;
  476.     }
  477.     is.dreg  = &(ce->c.ip); /* destination register for address */
  478.     is.dreg2 = &(ce->c.re[3]); /* destination register for template size */
  479.     is.dreg3 = &BitBucket;
  480.     is.sval  = ad(ce->c.ip + s + 1);    /* address to be pushed onto stack */
  481.     is.sval2 = s;  /* size of template */
  482.     is.sval3 = Search_limit;
  483.     is.dmod  = SoupSize;
  484.     is.dran2 = SoupSize;
  485.     is.dval  = ad(a + s + 1); /* start address for forward search */
  486.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  487.     is.mode  = 0; /* outward jump */
  488.     is.mode2 = 1;
  489.     is.dib = 1;
  490.     is.iip = 0;
  491. }
  492.  
  493. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  494.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  495.  * is.dreg = destination register, where value popped off stack will go
  496.  * is.dmod = value by which to modulus destination register
  497.  * is.dran = range within which to contain destination register
  498.  */
  499. void pret(ce) /* pop ip from stack */
  500. Pcells  ce;
  501. {   is.iip = is.dib = 1;
  502.     if (is.eins->exec)
  503.         return ;
  504.     is.dreg = &(ce->c.ip);
  505.     is.dmod = SoupSize;
  506.     is.iip = 0; is.dib = 1;
  507. }
  508.  
  509. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  510.  * is.dreg = destination register, where moved value will be placed
  511.  * is.sval = value to be placed in the dest reg
  512.  * is.dmod = value by which to modulus destination register
  513.  * is.dran = range within which to contain destination register
  514.  */
  515. void pmovdc(ce) /* dx = cx */
  516. Pcells  ce;
  517. {   I32s  treg;
  518.  
  519.     is.iip = is.dib = 1;
  520.     if (is.eins->exec)
  521.         return ;
  522.     treg = 3 + flaw(ce);
  523.     is.dreg = &(ce->c.re[mo(treg, NUMREG)]);
  524.     treg = 2 + flaw(ce);
  525.     is.sval = ce->c.re[mo(treg, NUMREG)];
  526.     is.iip = is.dib = 1;
  527.     if (is.dreg == &(ce->c.re[0]) || is.dreg == &(ce->c.re[1]))
  528.         is.dmod = SoupSize;
  529.     else
  530.         is.dran = SoupSize;
  531. }
  532.  
  533. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  534.  * is.dreg = destination register, where moved value will be placed
  535.  * is.sval = value to be placed in the dest reg
  536.  * is.dmod = value by which to modulus destination register
  537.  * is.dran = range within which to contain destination register
  538.  */
  539. void pmovba(ce) /* bx = ax */
  540. Pcells  ce;
  541. {   I32s  treg;
  542.  
  543.     is.iip = is.dib = 1;
  544.     if (is.eins->exec)
  545.         return ;
  546.     treg = 1 + flaw(ce);
  547.     is.dreg = &(ce->c.re[mo(treg, NUMREG)]);
  548.     treg = 0 + flaw(ce);
  549.     is.sval = ce->c.re[mo(treg, NUMREG)];
  550.     is.iip = is.dib = 1;
  551.     if (is.dreg == &(ce->c.re[0]) || is.dreg == &(ce->c.re[1]))
  552.         is.dmod = SoupSize;
  553.     else
  554.         is.dran = SoupSize;
  555. }
  556.  
  557. /* void movii(ce) is.dins->inst = is.sins->inst;
  558.  * is.dval  = address of destination instruction
  559.  * is.dins  = pointer to destination instruction
  560.  * is.sval  = address of source instruction
  561.  * is.sins  = pointer to source instruction
  562.  * is.dtra  = track of destination instruction
  563.  * is.sval2 = original value of destination instruction
  564.  */
  565. void pmovii(ce)
  566. Pcells  ce;
  567. {   I32s  tval;
  568.  
  569.     is.iip = is.dib = 1;
  570.     if (is.eins->exec)
  571.         return ;
  572.     tval = ce->c.re[0] + flaw(ce);
  573.     is.dval = ad(tval);
  574.     tval = ce->c.re[1] + flaw(ce);
  575.     is.sval = ad(tval);
  576. #if PLOIDY == 1
  577.     is.dins = &soup[is.dval];
  578.     is.sins = &soup[is.sval];
  579. #else /* PLOIDY > 1 */
  580.     is.dins = &soup[is.dval][ce->d.tr];
  581.     is.sins = &soup[is.sval][ce->d.tr];
  582. #endif /* PLOIDY > 1 */
  583.     is.sval2 = is.dins->inst;
  584.     is.dtra = ce->d.tr;
  585.     is.iip = is.dib = 1;
  586. #ifdef HSEX
  587.     if (ce->d.x_over_addr)
  588.        {
  589.        if ((!ce->d.mov_daught) && (!FindMate(ce)))
  590.           ce->d.x_over_addr = ce->d.mate_addr = 0;
  591.        else UseMate(ce);
  592.        }
  593. #endif
  594. }
  595.  
  596. /* void adr(ce) find address of a template
  597.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  598.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  599.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  600.  * is.dval  = starting address for forward search
  601.  * is.dval2 = starting address for backward search
  602.  * is.dreg  = destination register where target address will be stored
  603.  * is.dreg2 = destination register where template size will be stored
  604.  * is.dreg3 = destination register where offset of target will be stored
  605.  * is.sval  = return address if template size = 0
  606.  * is.sval2 = template size, 0 = no template
  607.  * is.sval3 = search limit, and return for distance actually searched
  608.  * is.dmod  = modulus value for is.dreg
  609.  * is.dmod2 = modulus value for is.dreg2
  610.  * is.dmod3 = modulus value for is.dreg3
  611.  * is.dran  = range to maintain for is.dreg
  612.  * is.dran2 = range to maintain for is.dreg2
  613.  * is.dran3 = range to maintain for is.dreg3
  614.  */
  615. void padr(ce) /* search outward for template, return address in ax */
  616. Pcells  ce; /* return template size in cx */
  617. {   I32s    a, s = 0;
  618.  
  619.     is.iip = is.dib = 1;
  620.     if (is.eins->exec)
  621.         return ;
  622.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  623.     while(1) /* find size of template, s = size */
  624.     {
  625. #if PLOIDY == 1
  626.     if(soup[ad(a + s)].inst != Nop0 &&
  627.            soup[ad(a + s)].inst != Nop1)
  628. #else /* PLOIDY > 1 */
  629.     if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  630.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  631. #endif /* PLOIDY > 1 */
  632.             break;
  633.         s++;
  634.     }
  635.     is.dreg  = &(ce->c.re[0]); /* destination register for address */
  636.     is.dreg2 = &(ce->c.re[2]); /* destination register for template size */
  637.     is.dreg3 = &BitBucket; /* throw away offset */
  638.     is.sval2 = s;  /* size of template */
  639.     is.sval3 = Search_limit;
  640.     is.dmod  = SoupSize;
  641.     is.dran2 = SoupSize;
  642.     is.dval  = ad(a + s + 1); /* start address for forward search */
  643.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  644.     is.mode  = 0; /* outward jump */
  645.     is.mode2 = 1;
  646.     is.iip = s + 1; is.dib = 1;
  647.     if (!s)
  648.         is.dreg  = &BitBucket; /* dump return value if template size == 0 */
  649. }
  650.  
  651. /* void adr(ce) find address of a template
  652.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  653.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  654.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  655.  * is.dval  = starting address for forward search
  656.  * is.dval2 = starting address for backward search
  657.  * is.dreg  = destination register where target address will be stored
  658.  * is.dreg2 = destination register where template size will be stored
  659.  * is.dreg3 = destination register where offset of target will be stored
  660.  * is.sval  = return address if template size = 0
  661.  * is.sval2 = template size, 0 = no template
  662.  * is.sval3 = search limit, and return for distance actually searched
  663.  * is.dmod  = modulus value for is.dreg
  664.  * is.dmod2 = modulus value for is.dreg2
  665.  * is.dmod3 = modulus value for is.dreg3
  666.  * is.dran  = range to maintain for is.dreg
  667.  * is.dran2 = range to maintain for is.dreg2
  668.  * is.dran3 = range to maintain for is.dreg3
  669.  */
  670. void padrb(ce) /* search backward for template, return address in ax */
  671. Pcells  ce; /* return template size in cx */
  672. {   I32s    a, s = 0;
  673.  
  674.     is.iip = is.dib = 1;
  675.     if (is.eins->exec)
  676.         return ;
  677.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  678.     while(1) /* find size of template, s = size */
  679.     {
  680. #if PLOIDY == 1
  681.     if(soup[ad(a + s)].inst != Nop0 &&
  682.            soup[ad(a + s)].inst != Nop1)
  683. #else /* PLOIDY > 1 */
  684.     if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  685.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  686. #endif /* PLOIDY > 1 */
  687.             break;
  688.         s++;
  689.     }
  690.     is.dreg  = &(ce->c.re[0]); /* destination register for address */
  691.     is.dreg2 = &(ce->c.re[2]); /* destination register for template size */
  692.     is.dreg3 = &BitBucket; /* throw away offset */
  693.     is.sval2 = s;  /* size of template */
  694.     is.sval3 = Search_limit;
  695.     is.dmod  = SoupSize;
  696.     is.dran2 = SoupSize;
  697.     is.dval  = ad(a + s + 1); /* start address for forward search */
  698.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  699.     is.mode  = 2; /* backward jump */
  700.     is.mode2 = 2;
  701.     is.iip = s + 1; is.dib = 1;
  702.     if (!s)
  703.         is.dreg  = &BitBucket; /* dump return value if template size == 0 */
  704. }
  705.  
  706. /* void adr(ce) find address of a template
  707.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  708.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  709.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  710.  * is.dval  = starting address for forward search
  711.  * is.dval2 = starting address for backward search
  712.  * is.dreg  = destination register where target address will be stored
  713.  * is.dreg2 = destination register where template size will be stored
  714.  * is.dreg3 = destination register where offset of target will be stored
  715.  * is.sval  = return address if template size = 0
  716.  * is.sval2 = template size, 0 = no template
  717.  * is.sval3 = search limit, and return for distance actually searched
  718.  * is.dmod  = modulus value for is.dreg
  719.  * is.dmod2 = modulus value for is.dreg2
  720.  * is.dmod3 = modulus value for is.dreg3
  721.  * is.dran  = range to maintain for is.dreg
  722.  * is.dran2 = range to maintain for is.dreg2
  723.  * is.dran3 = range to maintain for is.dreg3
  724.  */
  725. void padrf(ce) /* search forward for template, return address in ax */
  726. Pcells  ce; /* return template size in cx */
  727. {   I32s    a, s = 0;
  728.  
  729.     is.iip = is.dib = 1;
  730.     if (is.eins->exec)
  731.         return ;
  732.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  733.     while(1) /* find size of template, s = size */
  734.     {
  735. #if PLOIDY == 1
  736.     if(soup[ad(a + s)].inst != Nop0 &&
  737.            soup[ad(a + s)].inst != Nop1)
  738. #else /* PLOIDY > 1 */
  739.     if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  740.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  741. #endif /* PLOIDY > 1 */
  742.             break;
  743.         s++;
  744.     }
  745.     is.dreg  = &(ce->c.re[0]); /* destination register for address */
  746.     is.dreg2 = &(ce->c.re[2]); /* destination register for template size */
  747.     is.dreg3 = &BitBucket; /* throw away offset */
  748.     is.sval2 = s;  /* size of template */
  749.     is.sval3 = Search_limit;
  750.     is.dmod  = SoupSize;
  751.     is.dran2 = SoupSize;
  752.     is.dval  = ad(a + s + 1); /* start address for forward search */
  753.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  754.     is.mode  = 1; /* forward jump */
  755.     is.mode2 = 1;
  756.     is.iip = s + 1; is.dib = 1;
  757.     if (!s)
  758.         is.dreg  = &BitBucket; /* dump return value if template size == 0 */
  759. }
  760.  
  761. /* void malchm(ce) is.sval2 = mal(ce,&is.sval3,is.sval,is.mode2);
  762.  *                 *(is.dreg) = is.sval3;
  763.  *                 chmode(ce,is.sval3,is.sval2,is.mode);
  764.  * is.dreg  = destination register where allocated address is stored
  765.  * is.sval  = requested size of block for mal()
  766.  * is.sval2 = flawed size of block
  767.  * is.sval3 = suggested address, and allocated address
  768.  * is.mode  = memory protection mode (rwx), probably MemModeProt
  769.  * is.mode2 = memory allocation mode for mal()
  770.  */
  771. void pmal(ce)  /* allocate space for a new cell */
  772. Pcells  ce;  /* allocate space for a new cell */
  773. {   is.iip = is.dib = 1;
  774.     if (is.eins->exec)
  775.         return ;
  776.     is.dreg  = &(ce->c.re[0]);
  777.     is.sval  = ce->c.re[2];
  778.     is.sval3 = -1;
  779.     is.mode  = MemModeProt; /* only write privelages works at the moment */
  780.     is.mode2 = MalMode;
  781. }
  782.  
  783. /* void divide(ce) cell division
  784.  * is.sval  = offset of IP into daughter's genome
  785.  * is.sval2 = eject genome from soup = 0, 1 = leave in soup
  786.  * is.mode  = divide mode (3 steps)
  787.  */
  788. void pdivide(ce)  /* give life to new cell by puting in queue */
  789. Pcells  ce;
  790. {   is.iip = is.dib = 1;
  791.     if (is.eins->exec)
  792.         return ;
  793.     is.mode = 2;  /* full division */
  794. }
  795.  
  796. #endif  /* end of INST 1 */
  797.